package com.su02.multi.examples.mlp;

import com.su02.multi.chainrule.Function;
import com.su02.multi.examples.gd.GradientDescent;
import com.su02.multi.util.List2MapUtil;

import org.apache.commons.lang3.RandomUtils;

import java.util.ArrayList;
import java.util.List;

public class
Demo4MLP {

    public static void main(String[] args) {
        Function f = MultilayerPerceptron.MSELossFunction(List.of(2, 4, 4, 1), new TrainMatrix4MLP(entries(1000)));
        System.out.println(f.size());
        List<Double> start = new ArrayList<>(f.getBs().cardinality());
        for (int i = 0; i < f.getBs().cardinality(); i++) {
            start.add(RandomUtils.secure().randomDouble(0, 1.));
        }
        System.out.println(GradientDescent.optimize(f, List2MapUtil.convertList2Map(start), 0.01, 0));
    }

    private static List<TrainEntry4MLP> entries(int len) {
        List<TrainEntry4MLP> ans = new ArrayList<>(len);
        int p = 0;
        while (p < len) {
            double x0 = nextSign() * RandomUtils.secure().randomDouble(0., 1.);
            double x1 = nextSign() * RandomUtils.secure().randomDouble(0., 1.);
            ans.add(new TrainEntry4MLP(List.of(x0, x1), x0 * x0 + x1 * x1));
            p ++;
        }
        return ans;
    }

    private static double nextSign() {
        return RandomUtils.secure().randomBoolean() ? 1.0 : -1.0;
    }
}